/*
 * Copyright © 2020 www.noark.xyz All Rights Reserved.
 * 
 * 感谢您选择Noark框架，希望我们的努力能为您提供一个简单、易用、稳定的服务器端框架 ！
 * 除非符合Noark许可协议，否则不得使用该文件，您可以下载许可协议文件：
 * 
 * 		http://www.noark.xyz/LICENSE
 *
 * 1.未经许可，任何公司及个人不得以任何方式或理由对本框架进行修改、使用和传播;
 * 2.禁止在本项目或任何子项目的基础上发展任何派生版本、修改版本或第三方版本;
 * 3.无论你对源代码做出任何修改和改进，版权都归Noark研发团队所有，我们保留所有权利;
 * 4.凡侵犯Noark版权等知识产权的，必依法追究其法律责任，特此郑重法律声明！
 */
package com.company.qqsg.core.netty;

import java.util.Arrays;

import com.alibaba.fastjson.JSON;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.handler.codec.MessageToByteEncoder;
import xyz.noark.core.lang.ByteArray;
import xyz.noark.core.lang.ImmutableByteArray;
import xyz.noark.core.network.NetworkPacket;
import xyz.noark.core.network.NetworkProtocol;
import xyz.noark.core.util.StringUtils;
import xyz.noark.network.codec.AbstractPacketCodec;

/**
 * 封包编解码器
 *
 * @author 小流氓(176543888@qq.com)
 */
public class QqsgPacketCodec extends AbstractPacketCodec {
	@Override
	public <T> T decodeProtocol(ByteArray bytes, Class<T> klass) {
		return JSON.parseObject(bytes.array(), klass);
	}

	@Override
	public ByteArray encodePacket(NetworkProtocol networkProtocol) {
		String command = (String) networkProtocol.getOpcode();
		QqsgPacket packet = (QqsgPacket) networkProtocol.getPacket();

		if (networkProtocol.getProtocol().getClass() == String.class) {
			command = (String) packet.getOpcode();
		}

		// 协议编号
		byte[] commandBytes = command.getBytes();
		commandBytes = Arrays.copyOf(commandBytes, 32);

		byte[] bodyBytes = StringUtils.utf8Bytes((String) networkProtocol.getProtocol());

		int dataLen = 52 + bodyBytes.length;
		ByteBuf buffer = Unpooled.buffer(dataLen);
		buffer.writeInt(dataLen);
		buffer.writeBytes(commandBytes);

		buffer.writeInt(packet.getRid());
		/* 146 */ buffer.writeShort(packet.getSource());
		/* 147 */ buffer.writeShort(packet.getTarget());
		/* 148 */ buffer.writeShort(packet.getMode());
		/* 149 */ buffer.writeShort(packet.getDataType());
		/* 150 */ buffer.writeInt(packet.getParam());
		buffer.writeBytes(bodyBytes);

		return new ImmutableByteArray(buffer.array());
	}

	@Override
	public MessageToByteEncoder<?> lengthEncoder() {
		return new QqsgPacketEncoder();
	}

	@Override
	public ByteToMessageDecoder lengthDecoder() {
		return new QqsgPacketDecoder(this);
	}

	@Override
	public NetworkPacket decodePacket(ByteBuf byteBuf) {
		QqsgPacket packet = new QqsgPacket();
		packet.setLength(byteBuf.readableBytes());

		byte[] commandArray = new byte[32];
		byteBuf.readBytes(commandArray);
		String command = (new String(commandArray)).trim();
		packet.setOpcode(command);

		// 目前没看出来有什么用
		int rid = byteBuf.readInt();
		packet.setRid(rid);

		int source = byteBuf.readShort();
		packet.setSource(source);

		int target = byteBuf.readShort();
		packet.setTarget(target);

		int mode = byteBuf.readShort();
		packet.setMode(mode);

		int dataType = byteBuf.readShort();
		packet.setDataType(dataType);

		int param = byteBuf.readInt();
		packet.setParam(param);

		byte[] contentBytes = new byte[packet.getLength() - 48];
		byteBuf.readBytes(contentBytes);
		packet.setBytes(new ImmutableByteArray(contentBytes));

		System.out.println(command);
		System.out.println(new String(contentBytes));
		return packet;
	}
}